#ifndef RENDER_MANAGER_H
#define RENDER_MANAGER_H

#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QMatrix4x4>

// QOpenGL 相关
class QOpenGLContext;
class QOffscreenSurface;
class QOpenGLFramebufferObject;

class RenderView;
class Camera;
class Renderer;

/**
 * @brief The RenderManager class 渲染管理类
 *
 * 1. 多线程渲染
 * 2. 创建渲染数据
 *   2.1 渲染数据类型，如
 *     - 点(圆球)
 *     - 线(点云)
 *     - 箭头
 *     - 圆柱
 *     - 3ds 模型
 *     - ...
 * 3. 渲染逻辑接口
 */
class RenderManager : public QObject
{
    Q_OBJECT

    friend class RenderView;

public:
    explicit RenderManager(RenderView *render_form);
    ~RenderManager();

    /// 添加渲染模型
    /// 先添加后调用 requestInit 初始化
    void addRenderer(std::shared_ptr<Renderer> renderer);
    void removeRenderer(std::shared_ptr<Renderer> renderer);

    /// 请求相关渲染操作，在子线程中处理
    void requestInit();
    void requestResize();
    void requestRender();
    void requestStop();

    /// 获取相机对象
    std::shared_ptr<Camera> getCamera();

Q_SIGNALS:
    /// 双缓冲：通知 ui 线程同步帧缓冲区
    void blitFramebuffer();

private:
    void ensureFbo();

private Q_SLOTS:
    /// 子线程中处理相关渲染操作
    void init();
    void resize(int w, int h);
    void render();
    void cleanup();

private:
    RenderView *render_form_{ nullptr }; ///< 渲染窗口
    QThread *thread_{ nullptr };         ///< 渲染子线程
    QMutex mtx_render_;                  ///< 渲染互斥锁
    QWaitCondition cond_render_;         ///< 渲染条件变量

    /// 渲染资源，必须在子线程创建和释放
    std::shared_ptr<QOpenGLContext> ctx_{ nullptr }; ///< 渲染上下文
    QOpenGLFramebufferObject *fbo_{ nullptr }; ///< 子线程的帧缓冲区

    /// 渲染对象列表, 跨线程操作需要锁
    QMutex mtx_renderers_;
    QList<std::shared_ptr<Renderer>> renderers_; ///< 渲染节点

    std::shared_ptr<Camera> camera_{ nullptr }; ///< 相机
};

#endif // RENDER_MANAGER_H
